/* ---------------------------------------------Marlin Toolkit----------------------------------------*
Authors : Daniel Randle, Alex Bourne
Date Created : Mar 12 2013

File:
objectwindow.cpp

Description:
This file contains the definition for the ObjectWindow class functions along with any
helper functions associated with the class
*-----------------------------------------------------------------------------------------------------*/

// Includes
#include <objectwindow.h>
#include <hextiledialog.h>
#include <nsengine.h>

// Qt Includes
#include <qsplitter.h>
#include <qtreewidget.h>
#include <qboxlayout.h>
#include <qaction.h>

#ifdef DEBUG
#include <debug.h>
#endif

namespace ToolkitGui
{

/*-----------------------------*
|   class ObjectWindow BEGINS  |
*------------------------------*/
	ObjectWindow::ObjectWindow(QWidget * parent, Qt::WindowFlags f):QWidget(parent, f)
	{
		#ifdef DEBUG
		d = NULL;
		#endif
		_initObjects();
		_setupUi();
		_setupConnections();
	}


	void ObjectWindow::_initObjects()
	{
		splitter = new QSplitter(Qt::Horizontal, this);
		filter = new QTreeWidget(this);
		winLayV = new QVBoxLayout();
		
		// Dialogs
		hexTileD = new HexTileDialog(this);

		// Object Tree Widgets
		hexTileList = new QTreeWidget(this);
		staticObjectList = new QTreeWidget(this);
		lightList = new QTreeWidget(this);

		// Actions
		hexTileAct = new QAction(QDialog::tr("New"),this);
	}

	void ObjectWindow::_setupUi()
	{
		splitter->addWidget(filter);
		splitter->addWidget(hexTileList);
		splitter->addWidget(staticObjectList);
		splitter->addWidget(lightList);
		hexTileList->show();
		staticObjectList->hide();
		lightList->hide();

		winLayV->addWidget(splitter);
		setLayout(winLayV);

		filter->setMinimumWidth(140);
		filter->setMaximumWidth(140);
		
		_setupHeaders();
		_createFilterItems();
		_fillContextMenus();

		hexTileList->setContextMenuPolicy(Qt::ActionsContextMenu);
		filter->expandAll();
	}

	void ObjectWindow::_setupHeaders()
	{
		filter->setHeaderHidden(true);
		QStringList hexTileHeaders,staticObjectHeaders,lightHeaders;
		hexTileHeaders.append("Tile Name");
		hexTileHeaders.append("References");
		hexTileHeaders.append("Object ID");

		staticObjectHeaders.append("Object Name");
		staticObjectHeaders.append("References");
		staticObjectHeaders.append("Object ID");

		lightHeaders.append("Light Name");
		lightHeaders.append("References");
		lightHeaders.append("Object ID");

		hexTileList->setHeaderLabels(hexTileHeaders);
		staticObjectList->setHeaderLabels(staticObjectHeaders);
		lightList->setHeaderLabels(lightHeaders);
	}

	void ObjectWindow::_createFilterItems()
	{
		QTreeWidgetItem * tiles = new QTreeWidgetItem();
		QTreeWidgetItem * fullTiles = new QTreeWidgetItem();
		QTreeWidgetItem * halfTiles = new QTreeWidgetItem();

		QTreeWidgetItem * staticObjects = new QTreeWidgetItem();
		QTreeWidgetItem * trees = new QTreeWidgetItem();
		QTreeWidgetItem * rocks = new QTreeWidgetItem();
		QTreeWidgetItem * structures = new QTreeWidgetItem();

		QTreeWidgetItem * lights = new QTreeWidgetItem();
		QTreeWidgetItem * pointLights = new QTreeWidgetItem();
		QTreeWidgetItem * spotLights = new QTreeWidgetItem();

		tiles->setText(0,"Tiles");
		fullTiles->setText(0,"Full Tiles");
		halfTiles->setText(0,"Half Tiles");

		staticObjects->setText(0,"Static Objects");
		trees->setText(0,"Trees");
		rocks->setText(0,"Rocks");
		structures->setText(0,"Structures");

		lights->setText(0,"Lights");
		pointLights->setText(0,"Point Lights");
		spotLights->setText(0,"Spot Lights");

		tiles->addChild(fullTiles);
		tiles->addChild(halfTiles);

		staticObjects->addChild(trees);
		staticObjects->addChild(rocks);
		staticObjects->addChild(structures);

		lights->addChild(pointLights);
		lights->addChild(spotLights);

		treeWidgetMap[tiles->text(0)] = hexTileList;
		treeWidgetMap[staticObjects->text(0)] = staticObjectList;
		treeWidgetMap[lights->text(0)] = lightList;

		filter->addTopLevelItem(tiles);
		filter->addTopLevelItem(staticObjects);
		filter->addTopLevelItem(lights);
		filter->setCurrentItem(tiles);
	}

	void ObjectWindow::_fillContextMenus()
	{
		hexTileList->addAction(hexTileAct);
	}

	void ObjectWindow::_setupConnections()
	{
		connect(filter,SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),this,SLOT(onFilterItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
		connect(hexTileAct, SIGNAL(triggered()), this, SLOT(onHexTileAct()));
		connect(hexTileList,SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(onDoubleClick(QTreeWidgetItem *, int)));
		connect(staticObjectList,SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(onDoubleClick(QTreeWidgetItem *, int)));
		connect(lightList,SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(onDoubleClick(QTreeWidgetItem *, int)));
	}

	void ObjectWindow::_clearTreeWidgets()
	{
		hexTileList->clear();
		staticObjectList->clear();
		lightList->clear();
	}

	void ObjectWindow::onFilterItemChanged(QTreeWidgetItem* current,QTreeWidgetItem* previous)
	{
		if (current != 0)
		{
			if ( current->parent() != 0 )
				current = current->parent();

			if (previous != 0)
			{
				if (previous->parent() != 0)
					previous = previous->parent();
				if (!treeWidgetMap[previous->text(0)]->isHidden())
					treeWidgetMap[previous->text(0)]->hide();
			}
			treeWidgetMap[current->text(0)]->show();
		}
	}

	void ObjectWindow::onHexTileAct()
	{
		if (hexTileD->exec() == QDialog::Accepted)
		{
			NSObject * base = engine->addObject(NSObject::HexTile,engine->getShader("LightShader"),hexTileD->nameLE->text().toStdString(),hexTileD->modelLE->text().toStdString(),"Meshes/Tiles","Textures/Tiles");
		}
		update();
	}

	void ObjectWindow::onDoubleClick(QTreeWidgetItem * item, int column)
	{
		NSMapBuilder * mb = engine->getMapBuilder();
		mb->setObject(engine->getObject(item->text(0).toStdString()));
		emit activateBuild();
	}

	void ObjectWindow::setEngine(NSEngine * eng)
	{
		engine = eng;
	}

	void ObjectWindow::update()
	{
		_clearTreeWidgets();
		NSShaderSet::Iterator iter = engine->shadersBegin();
		while (iter != engine->shadersEnd() )
		{
			NSObjectSet::ObjectIterator iter2 = engine->objectsBegin(*iter);
			while (iter2 != engine->objectsEnd(*iter))
			{
				NSObject * currentObj = *iter2;
				QTreeWidgetItem * item = new QTreeWidgetItem();
				item->setData(0,Qt::DisplayRole,QString(currentObj->getName().c_str()));
				item->setData(1,Qt::DisplayRole,engine->getReferenceCount(currentObj));
				item->setData(2,Qt::DisplayRole,currentObj->getID());

				switch (currentObj->getObjectType())
				{
				case (NSObject::HexTile):
					if (hexTileList->findItems(item->text(0),Qt::MatchCaseSensitive).isEmpty())
						hexTileList->addTopLevelItem(item);
					break;
				case (NSObject::SpotLight):
					if (lightList->findItems(item->text(0),Qt::MatchCaseSensitive).isEmpty())
						lightList->addTopLevelItem(item);
					break;
				case (NSObject::PointLight):
					if (lightList->findItems(item->text(0),Qt::MatchCaseSensitive).isEmpty())
						lightList->addTopLevelItem(item);
					break;
				case (NSObject::Base):
					if (staticObjectList->findItems(item->text(0),Qt::MatchCaseSensitive).isEmpty())
						staticObjectList->addTopLevelItem(item);
					break;
				case (NSObject::DirectionalLight):
					if (lightList->findItems(item->text(0),Qt::MatchCaseSensitive).isEmpty())
						lightList->addTopLevelItem(item);
					break;
				}
				++iter2;
			}
			++iter;
		}
	}

	#ifdef DEBUG
	void ObjectWindow::setDebug(Debug * debug)
	{
		d = debug;
	}
	#endif

}